package jude.java.money.batch.task;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import jude.java.money.batch.memory.TKSites;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;

public class DotTK implements Runnable {
	
	private static final String LOGIN_URL = "http://my.dot.tk/cgi-bin/login01.taloha";
	private static final String LOGIN2_URL = "http://my.dot.tk/cgi-bin/login02.taloha";
	private static final String DOMAIN_LIST_URL = "http://my.dot.tk/cgi-bin/rnt09.taloha";
	
	private String usr;
	private String pwd;
	
	public DotTK(String username, String password) {
		this.usr = username;
		this.pwd = password;
	}

	@Override
	public void run() {
		try {
			findDomains(this.usr, this.pwd);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void findDomains(String user, String pwd) throws HttpException, IOException {
		System.out.println("//Looking... " + user);
		HttpClient client = getHttpClient();
		PostMethod post = getLoginMethod(user, pwd);
		int status = client.executeMethod(post);
		if (status != 200) {
			showResult(status, post);
			return;
		}
		post.releaseConnection();
		GetMethod get = getDomainListMethod();
		status = client.executeMethod(get);
		if (status != 200) {
			showResult(status, get);
			return;
		}
		String content = getResponse(get);
		List<String> domains = findDomains(content);
		System.out.println("//\t" + domains.size());
		TKSites.updateSites(user, domains);
	}
	
	private List<String> findDomains(String resp) {
		List<String> r = new ArrayList<String>();
		Pattern p = Pattern.compile("<strong>([A-Z0-9\\-_.]{4,30}\\.TK)</strong>");
		Matcher m = p.matcher(resp);
		int n = 0;
		while(m.find(n)) {
			String domain = m.group(1).toLowerCase();
			r.add(domain);
			n = m.end(0);
//			System.out.println(domain);
		}
		return r;
	}
	
	private void showResult(int status, HttpMethodBase method) {
		if (status != 200) {
			if (status >= 300 && status < 400) {
				System.out.println(status + ": " + method.getResponseHeader("location"));
			}
		}
	}

	private HttpClient getHttpClient() {
		HttpClient client = new HttpClient();
		HttpConnectionManagerParams p = client.getHttpConnectionManager().getParams();
		p.setConnectionTimeout(30000);
		p.setSoTimeout(60000);
		return client;
	}
	
	private PostMethod getLoginMethod(String user, String pwd) {
		PostMethod post = new PostMethod(LOGIN2_URL);
		initMethod(post);
//		post.addRequestHeader("", "");
		NameValuePair[] pairs = new NameValuePair[2];
		pairs[0] = new NameValuePair("fldemail", user);
		pairs[1] = new NameValuePair("fldpassword", pwd);
		post.setRequestBody(pairs);
//		post.setFollowRedirects(true);
		return post;
	}
	
	private GetMethod getDomainListMethod() {
		GetMethod get = new GetMethod(DOMAIN_LIST_URL);
		initMethod(get);
		return get;
	}
	
	private void initMethod(HttpMethodBase method) {
		method.addRequestHeader("Referer", LOGIN_URL);
		method.addRequestHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; CIBA)");
		method.addRequestHeader("Connection", "Keep-Alive");
	}
	
	private String getResponse(HttpMethodBase post) throws IOException {
//		long len = post.getResponseContentLength();
		StringBuffer sb = new StringBuffer();
		int max = -1;
//		ByteArrayOutputStream outstream = new ByteArrayOutputStream(max);
        char[] buffer = new char[1024];
        int n, t=0;
        InputStream instream = post.getResponseBodyAsStream();
        InputStreamReader reader = new InputStreamReader(instream, "UTF-8");
        while ((n = reader.read(buffer)) > 0) {
            sb.append(buffer, 0, n);
			t += n;
			if (max > 0 && t >= max)
				break;
        }
        return sb.toString();
	}
	
}
